home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1987, 1988 Stanley T. Shebs, University of Utah. */
- /* Copyright 1988 by Chris D. Peterson, MIT. */
- /* Many improvements by Tim Moore, University of Utah. */
- /* This program may be used, copied, modified, and redistributed freely */
- /* for noncommercial purposes, so long as this notice remains intact. */
-
- #pragma comment(exestr, "@(#) X11.c 12.1 95/05/09 ")
-
- /* RCS $Header: X11.c,v 1.3 88/07/19 11:10:03 shebs Exp $ */
-
- /* Interface implementations for the X11 version of xconq. */
-
- #include "config.h"
- #include "misc.h"
- #include "period.h"
- #include "side.h"
- #include "unit.h"
- #include "map.h"
- #include "global.h"
-
- /* careful of the path of the X header files. */
-
- #ifdef UNIX
- #include <signal.h> /* needed for ^C disabling */
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #endif /* UNIX */
-
- /* various bitmap definitions. */
-
- #define dots_width 16
- #define dots_height 16
- static char dots_bits[] = {
- 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
- #define mask_width 16
- #define mask_height 16
- static char mask_bits[] = {
- 0xe0, 0x03, 0xd8, 0x0f, 0xb4, 0x19, 0x8a, 0x21,
- 0x86, 0x61, 0x85, 0x41, 0x83, 0xc1, 0xff, 0xff,
- 0xff, 0xff, 0x83, 0xc1, 0x82, 0xa1, 0x86, 0x61,
- 0x84, 0x51, 0x98, 0x2d, 0xf0, 0x1b, 0xc0, 0x07};
-
- #define curs_width 16
- #define curs_height 16
- static char curs_bits[] = {
- 0xe0, 0x03, 0x98, 0x0c, 0x84, 0x10, 0x82, 0x20,
- 0x82, 0x20, 0x81, 0x40, 0x81, 0x40, 0xff, 0x7f,
- 0x81, 0x40, 0x81, 0x40, 0x82, 0x20, 0x82, 0x20,
- 0x84, 0x10, 0x98, 0x0c, 0xe0, 0x03, 0x00, 0x00};
-
- #define bomb1_width 32
- #define bomb1_height 32
- static char bomb1_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xc0, 0x01, 0x00, 0x00, 0xf0, 0x07, 0x00,
- 0x00, 0xf0, 0x07, 0x00, 0x00, 0xf8, 0x0f, 0x00,
- 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xfc, 0x0f, 0x00,
- 0x00, 0xfe, 0x1f, 0x00, 0x00, 0xfe, 0x3f, 0x00,
- 0x00, 0xfe, 0x3f, 0x00, 0x00, 0xfc, 0x1f, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
- #define bomb2_width 32
- #define bomb2_height 32
- static char bomb2_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00,
- 0x00, 0xf8, 0x07, 0x00, 0x00, 0xfc, 0x0f, 0x00,
- 0x00, 0xfc, 0x1f, 0x00, 0x00, 0xfe, 0x1f, 0x00,
- 0x00, 0xfe, 0x3f, 0x00, 0x00, 0xfc, 0x1f, 0x00,
- 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00,
- 0x00, 0xf0, 0x03, 0x00, 0x00, 0xe0, 0x03, 0x00,
- 0x00, 0xf0, 0x07, 0x00, 0x00, 0xf0, 0x07, 0x00,
- 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00,
- 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf8, 0x1f, 0x00,
- 0x00, 0xf8, 0x1f, 0x00, 0x00, 0xfc, 0x1f, 0x00,
- 0x00, 0xff, 0x7f, 0x00, 0xc0, 0xff, 0xff, 0x03,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
- #define bomb3_width 32
- #define bomb3_height 32
- static char bomb3_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xfe, 0xe2, 0xa3, 0x3f,
- 0x00, 0xfc, 0x1f, 0x00, 0x3c, 0xff, 0x7f, 0x7c,
- 0x80, 0xff, 0xff, 0x00, 0xc0, 0xff, 0xff, 0x01,
- 0xc0, 0xff, 0xff, 0x01, 0xe0, 0xff, 0xff, 0x03,
- 0xe0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x03,
- 0xe0, 0xff, 0xff, 0x01, 0xe0, 0xff, 0xff, 0x49,
- 0x82, 0xff, 0xff, 0x34, 0x14, 0xfe, 0x3f, 0x42,
- 0xe2, 0xff, 0x9f, 0x34, 0x40, 0xfe, 0x3f, 0x41,
- 0xbe, 0xfd, 0xdf, 0x1e, 0x00, 0xf8, 0x1f, 0x01,
- 0xfe, 0xfd, 0xdf, 0x7f, 0x00, 0xfc, 0x1f, 0x00,
- 0x00, 0xfc, 0x1f, 0x00, 0x00, 0xfc, 0x3f, 0x00,
- 0x00, 0xfe, 0x1f, 0x00, 0x00, 0xfe, 0x3f, 0x00,
- 0x00, 0xff, 0x3f, 0x00, 0xc0, 0xff, 0xff, 0x00,
- 0xfc, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x7f,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
- #define bomb4_width 32
- #define bomb4_height 32
- static char bomb4_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00,
- 0x00, 0x78, 0x10, 0x00, 0x00, 0x0f, 0x46, 0x00,
- 0x80, 0x61, 0x81, 0x00, 0xc0, 0x1c, 0x00, 0x01,
- 0x40, 0x02, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,
- 0x20, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
- 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
- 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
- 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
- /* This is the name of a family of programs, so argv[0] inadequate. */
-
- #define PROGRAMNAME "xconq"
-
- /* Name of default font - why is this wired in? */
-
- #define STANDARD "standard"
-
- /* Magic number meaning that this pixmap intentionally left blank. */
-
- #define NOPIXMAP 17
-
- #define INFOLINES 4
-
- #define BH 32
-
- /* Use with caution - variable name "side" embedded! */
-
- #define sd() ((Screeno *) side->display)
-
- #define sdd() (((Screeno *) side->display)->disp)
-
- typedef unsigned int unint;
-
- /* GC rules are for different fonts etc, but not colors or bitmaps. */
-
- typedef struct a_screen {
- Display *disp;
- GC gc; /* a tmp graphics context for this display */
- GC flashgc; /* The gc for drawing the flash lines. */
- GC textgc; /* foreground on background text */
- GC icongc; /* icon graphics context */
- GC invicongc; /* icon gc inverted colors. */
- GC varicongc; /* This is an icon gc with variable fgcolor. */
- GC unitgc; /* unit bitmap printing gc. */
- GC unittextgc; /* unit text printing gc. */
- GC cleargc; /* The gc to use for clearing areas. */
- GC clearbitgc; /* gc for clearing bitmaps */
- XFontStruct *textfont; /* font for text display */
- XFontStruct *iconfont; /* utility font with assorted icons */
- XFontStruct *unitfont; /* font for unit characters */
- Pixmap bombpics[4]; /* mushroom clouds */
- Pixmap unitpics[MAXUTYPES]; /* used instead of font sometimes */
- Pixmap wbdots, bwdots; /* blue border and dotted backgrounds */
- Cursor curs; /* the cursor object itself */
- } Screeno;
-
- extern int giventime;
-
- /* Random function declarations. */
-
- XFontStruct * open_font();
- Pixmap load_bitmap();
- void get_font_size();
- Cursor make_cursor();
-
- /* The array of screen objects. */
-
- Screeno screens[MAXSIDES]; /* All the "screen objects" */
-
- /* Values of parameters generally tied to fonts and the like. */
-
- int hw = 20;
- int hh = 22;
- int hch = 17;
- int margin = 2;
- int bd = 1;
-
- int helpwinlines = 1; /* size of help window */
-
- bool rootcursor; /* true if using parent window's cursor */
-
- /* Put in a default player, probably the invoker of the program. */
- /* An empty host name will confuse everybody. */
-
- add_default_player()
- {
- #ifdef UNIX
- add_player(TRUE, getenv("DISPLAY"));
- #endif /* UNIX */
- }
-
- /* Ignore ^C if humans in the game, do it otherwise, including when the */
- /* last human player turns into a machine (this is called by option cmd). */
- /* Attempts to be more clever seem to be bad news. */
-
- init_sighandlers()
- {
- #ifdef UNIX
- if (numhumans > 0 && !Debug) {
- signal(SIGINT, SIG_IGN);
- } else {
- signal(SIGINT, SIG_DFL);
- }
- #endif /* UNIX */
- }
-
- /* Note that the open_display function syncronizes the X server when the */
- /* Debug flag is set. */
-
- open_display(side)
- Side *side;
- {
- if (Debug) printf("starting open_display\n");
-
- side->display = (long) &(screens[side_number(side)]);
-
- if (Debug) printf("open_display: XopenDisplay('%s')\n", side->host);
-
- if(NULL == (sdd() = XOpenDisplay(side->host)))
- {
- fprintf(stderr, "Cannot open display ('%s')\n", side->host);
- exit(1);
- }
- if (Debug) {
- XSynchronize(sdd(), TRUE);
- printf("Synching the X server.\n");
- }
- init_cmaps(side);
- side->main = XCreateSimpleWindow(sdd(), DefaultRootWindow(sdd()),
- 50, 3,
- display_width(side), display_height(side),
- 3, white_color(side), black_color(side));
- XSetWindowColormap(sdd(), side->main, side->cmap);
- read_options(side);
- if (Debug) printf("done open_display\n");
- return (sdd() != NULL);
- }
-
- /* A predicate that tests whether our display can safely be written to. */
-
- active_display(side)
- Side *side;
- {
- return (side && side->host && !side->lost && side->display);
- }
-
- display_width(side)
- Side *side;
- {
- return ((19 * XDisplayWidth(sdd(), DefaultScreen(sdd()))) / 20);
- }
-
- display_height(side)
- Side *side;
- {
- return ((19 * XDisplayHeight(sdd(), DefaultScreen(sdd()))) / 20);
- }
-
- /* Most X displays have enough screen to do a world map. */
-
- world_display(side) Side *side; { return TRUE; }
-
- /* Could use handlers for X failures... */
-
- /* Do misc setup thingies. */
-
- /* Do the rigmarole to convert all those short arrays into X-approved */
- /* Bitmaps. Note that this has to be for *each* display separately (!) */
- /* Also get the cursor shape. If the hardware can't hack the desired */
- /* cursor size, warn about it and just use the root window's cursor. */
- /* 0x0 cursor specs seem to be don't cares - machine can handle any size */
- /* X11 also needs gazillions of GCs, since we've got so many fonts and */
- /* colors and bitmaps. */
-
- init_misc(side)
- Side *side;
- {
- int u, w, h;
- unsigned long mask;
- XGCValues values;
- Pixmap mmask, mcurs, dots;
- GC gc;
-
- side->margin = margin;
- side->bd = bd;
- side->hw = hw;
- side->hh = hh;
- side->hch = hch;
- mask = GCForeground | GCBackground;
- values.foreground = side->fgcolor;
- values.background = side->bgcolor;
- gc = XCreateGC(sdd(), side->main, mask, &values);
- sd()->gc = XCreateGC(sdd(), side->main, mask, &values);
- sd()->flashgc = XCreateGC(sdd(), side->main, mask, &values);
- sd()->textgc = XCreateGC(sdd(), side->main, mask, &values);
- sd()->icongc = XCreateGC(sdd(), side->main, mask, &values);
- sd()->varicongc = XCreateGC(sdd(), side->main, mask, &values);
- sd()->unitgc = XCreateGC(sdd(), side->main, mask, &values);
- sd()->unittextgc = XCreateGC(sdd(), side->main, mask, &values);
- values.foreground = side->bgcolor;
- values.background = side->fgcolor;
- sd()->invicongc = XCreateGC(sdd(), side->main, mask, &values);
- values.function = GXclear;
- mask = GCFunction;
- sd()->cleargc = XCreateGC(sdd(), side->main, mask, &values);
-
- sd()->textfont = open_font(side, TEXTFONT, "TextFont", NULL);
- get_font_size(sd()->textfont, &(side->fw), &(side->fh) );
- sd()->iconfont = open_font(side, ICONFONT, "IconFont", sd()->textfont);
- get_font_size(sd()->iconfont, &(side->hw), &(side->hh) );
- if (period.fontname != NULL && strlen(period.fontname) > 0) {
- sd()->unitfont =
- open_font(side, period.fontname, "UnitFont", sd()->textfont);
- get_font_size(sd()->unitfont, &(side->uw), &(side->uh) );
- } else {
- sd()->unitfont =
- open_font(side, STANDARD, "UnitFont", sd()->textfont);
- get_font_size(sd()->unitfont, &(side->uw), &(side->uh) );
- }
- XSetFont(sdd(), sd()->textgc, sd()->textfont->fid);
- XSetFont(sdd(), sd()->icongc, sd()->iconfont->fid);
- mask = GCFillStyle | GCGraphicsExposures;
- values.fill_style = FillSolid;
- values.graphics_exposures = FALSE;
- XChangeGC(sdd(), sd()->unitgc, mask, &values);
- XSetFont(sdd(), sd()->unittextgc, sd()->unitfont->fid);
- XSetFont(sdd(), sd()->invicongc, sd()->iconfont->fid);
- XSetFont(sdd(), sd()->varicongc, sd()->iconfont->fid);
- XSetFunction(sdd(), sd()->flashgc, GXinvert);
-
- mmask = XCreateBitmapFromData(sdd(), side->main,
- mask_bits, mask_width, mask_height);
- mcurs = XCreateBitmapFromData(sdd(), side->main,
- curs_bits, curs_width, curs_height);
-
- dots = XCreateBitmapFromData(sdd(), side->main,
- dots_bits, dots_width, dots_height);
-
- sd()->bombpics[0] = XCreateBitmapFromData(sdd(), side->main,
- bomb1_bits, bomb1_width, bomb1_height);
- sd()->bombpics[1] = XCreateBitmapFromData(sdd(), side->main,
- bomb2_bits, bomb2_width, bomb2_height);
- sd()->bombpics[2] = XCreateBitmapFromData(sdd(), side->main,
- bomb3_bits, bomb3_width, bomb3_height);
- sd()->bombpics[3] = XCreateBitmapFromData(sdd(), side->main,
- bomb4_bits, bomb4_width, bomb4_height);
- for_all_unit_types(u) {
- if (utypes[u].bitmapname && (strlen(utypes[u].bitmapname) > 0)) {
- sd()->unitpics[u] = load_bitmap(side, utypes[u].bitmapname);
- } else {
- utypes[u].bitmapname = NULL;
- }
- }
- if (Debug) printf("Bitmaps stored ...\n");
-
- sd()->wbdots = XCreatePixmap(sdd(), side->main, dots_width, dots_height,
- DefaultDepth(sdd(), DefaultScreen(sdd())));
- sd()->bwdots = XCreatePixmap(sdd(), side->main, dots_width, dots_height,
- DefaultDepth(sdd(), DefaultScreen(sdd())));
-
- /* Since clearbitgc has to have a depth of 1 we'll */
- /* hang it off bombpics[0] */
- mask = GCFunction;
- values.function = GXclear;
- sd()->clearbitgc = XCreateGC(sdd(), sd()->bombpics[0], mask, &values);
-
- XSetForeground(sdd(), gc, side->fgcolor);
- XSetBackground(sdd(), gc, side->bgcolor);
- XSetStipple(sdd(), gc, dots);
- XSetFillStyle(sdd(), gc, FillOpaqueStippled);
- XFillRectangle(sdd(), sd()->wbdots, gc, 0, 0, dots_width, dots_height);
-
- XSetForeground(sdd(), gc, side->bgcolor);
- XSetBackground(sdd(), gc, side->fgcolor);
- XFillRectangle(sdd(), sd()->bwdots, gc, 0, 0, dots_width, dots_height);
- if (Debug) printf("Tiles stored ...\n");
-
- rootcursor = FALSE;
- XQueryBestCursor(sdd(), side->main, curs_width, curs_height, &w, &h);
- if (Debug) printf("Allowed cursor shape is %dx%d\n", w, h);
- if (w >= curs_width && h >= curs_height) {
- sd()->curs =
- make_cursor(side, mcurs, mmask, white_color(side),
- black_color(side), 7, 7);
-
- } else {
- fprintf(stderr, "Warning: Can't have %dx%d cursors on \"%s\"!\n",
- curs_width, curs_height, side->host);
- fprintf(stderr, "Using default cursor...\n");
- rootcursor = TRUE;
- }
- if (Debug) printf("Cursor stored ...\n");
- XFreeGC(sdd(), gc);
- XFreePixmap(sdd(), dots);
- XFreePixmap(sdd(), mmask);
- XFreePixmap(sdd(), mcurs);
- }
-
- /* Since XCreatePixmapCursor() takes XColors and not pixel values we */
- /* have to look the colors associated with the foreground and */
- /* background pixel values up in the color table and pass them to */
- /* XCreatePixmapCursor(). */
-
- Cursor
- make_cursor(side, curs, mask, foreground, background, x, y)
- Side *side;
- Pixmap curs, mask;
- unsigned long foreground, background;
- unsigned int x, y;
- {
- XColor defs[2];
-
- defs[0].pixel = foreground;
- defs[1].pixel = background;
- XQueryColors(sdd(), side->cmap, defs, 2);
- return XCreatePixmapCursor(sdd(), curs, mask, &defs[0], &defs[1], x, y);
- }
-
- /* Since font lookup is still not smart among Xs, this is a general routine */
- /* that can deal with unopenable, missing, etc, fonts, as well as the use of */
- /* .Xdefaults. One of the inputs is another font that can be substituted if */
- /* necessary. */
-
- XFontStruct *
- open_font(side, name, xdefault, altfont)
- Side *side;
- char *name, *xdefault;
- XFontStruct * altfont;
- {
- char *firstname, *altname;
- XFontStruct * font;
-
- if ((altname = XGetDefault(sdd(), PROGRAMNAME, xdefault)) != NULL)
- name = altname;
- firstname = name;
- if ((font = XLoadQueryFont(sdd(), name)) == NULL) {
- add_font_path(side,XFONTPATH);
- if ((font = XLoadQueryFont(sdd(), name)) == NULL) {
- fprintf(stderr, "Can't open font \"%s\" on \"%s\"\n",
- name, side->host);
- if (altfont != NULL) {
- fprintf(stderr, "Substituting another font...\n");
- return altfont;
- } else {
- fprintf(stderr, "No font to substitute!!\n");
- exit(1);
- }
- }
- }
- if (Debug) printf("Opened font \"%s\" ...\n", name);
- return font;
- }
-
- /* Force X11 font fanciness into semblance of X10 font plainness. */
-
- void
- get_font_size(font, width, height)
- XFontStruct * font;
- short *width, *height;
- {
- #ifdef SCO_UNIX
- /* this seems to work best; for some reason, the bounds width
- * doesn't seem to give the right result.
- */
- *width = XTextWidth(font, "12345678", 8) / 8;
- *height = font->max_bounds.ascent + font->max_bounds.descent;
- #else
- *width = font->max_bounds.rbearing - font->min_bounds.lbearing;
- *height = font->max_bounds.ascent + font->max_bounds.descent;
- #endif /* SCO_UNIX */
- if (Debug) {
- printf("rbearing = %d lbearing = %d\n",
- (int)font->max_bounds.rbearing, (int)font->min_bounds.lbearing);
- printf("returning font size %d %d\n", (int)*width, (int)*height);
- }
- }
-
- /* Try to load a bitmap of the given name - can be either X11-only (.b11) */
- /* or X10 (.b) bitmaps, but prefer X11 flavor. */
-
- Pixmap
- load_bitmap(side, name)
- Side *side;
- char *name;
- {
- int w, h, junk, a;
- Pixmap rslt;
-
- make_pathname(NULL, name, "b11", spbuf);
- a = XReadBitmapFile(sdd(), side->main, spbuf, &w, &h, &rslt, &junk, &junk);
- if (a == BitmapSuccess) return rslt;
- make_pathname(XCONQLIB, name, "b11", spbuf);
- a = XReadBitmapFile(sdd(), side->main, spbuf, &w, &h, &rslt, &junk, &junk);
- if (a == BitmapSuccess) return rslt;
- make_pathname(XCONQLIB, name, "b", spbuf);
- a = XReadBitmapFile(sdd(), side->main, spbuf, &w, &h, &rslt, &junk, &junk);
- if (a == BitmapSuccess) return rslt;
- fprintf(stderr, "Bitmap name \"%s\" not found anywhere!\n", name);
- return (-1);
- }
-
- /* This routine has to be able to cope with window managers constraining */
- /* size. Actually, the main window was already opened when the display */
- /* was opened, so the name is not quite accurate! */
-
- create_main_window(side)
- Side *side;
- {
- Pixmap dots;
- XSizeHints hints;
-
- XStoreName(sdd(), side->main, PROGRAMNAME);
- dots = (side->bonw ? sd()->bwdots : sd()->wbdots);
- XSetWindowBackgroundPixmap(sdd(), side->main, dots);
-
- hints.width = side->mw;
- hints.height = side->mh;
- hints.min_width = side->mw;
- hints.min_height = side->mh;
- hints.flags = PSize|PMinSize;
- XSetNormalHints(sdd(), side->main, &hints);
- }
-
- /* Help window is not necessarily a subwindow, though it might be sometimes. */
-
- create_help_window(side)
- Side *side;
- {
- helpwinlines =
- max(45, (24 + period.numrtypes + period.numttypes + period.numutypes));
-
- side->help = XCreateSimpleWindow(sdd(), DefaultRootWindow(sdd()),
- 0, 0, 80*side->fw+1,
- helpwinlines*side->fh+1,
- 1, side->fgcolor, side->bgcolor);
- XStoreName(sdd(), side->help, "xconq-help");
- XSetWindowColormap(sdd(), side->help, side->cmap);
- }
-
- /* Subwindow creator. If name is not null, create a split window. */
-
- create_window(side, x, y, w, h, name)
- Side *side;
- int x, y, w, h;
- char *name;
- {
- int win;
- win = XCreateSimpleWindow(sdd(),
- name ? DefaultRootWindow(sdd()) : side->main,
- x, y, w, h, 1, side->fgcolor, side->bgcolor);
- if (name)
- XStoreName(sdd(), win, name);
- XSetWindowColormap(sdd(), win, side->cmap);
- return win;
- }
-
- /* Do little things necesary to make it all go, in this case mapping all */
- /* the windows (except help win). */
-
- fixup_windows(side)
- Side *side;
- {
- XMapWindow(sdd(), side->main);
- XMapSubwindows(sdd(), side->main);
- if (side->split) {
- XMapWindow(sdd(), side->state);
- XMapWindow(sdd(), side->map);
- XMapWindow(sdd(), side->world);
- }
- if (!giventime) XUnmapWindow(sdd(), side->clock);
- if (!rootcursor) XDefineCursor(sdd(), side->map, sd()->curs);
- }
-
- /* Specify the sorts of input that will be allowed - main window needs to */
- /* see mouse buttons so unit type selection works right. */
-
- enable_input(side)
- Side *side;
- {
- if (side->split) {
- XSelectInput(sdd(), side->main,
- KeyPressMask|ExposureMask|StructureNotifyMask);
- XSelectInput(sdd(), side->map,
- KeyPressMask|ButtonPressMask|ExposureMask|StructureNotifyMask);
- XSelectInput(sdd(), side->state,
- KeyPressMask|ButtonPressMask|ExposureMask);
- }
- else {
- XSelectInput(sdd(), side->main, KeyPressMask|ExposureMask);
- XSelectInput(sdd(), side->map, ButtonPressMask|ExposureMask);
- XSelectInput(sdd(), side->state, ButtonPressMask|ExposureMask);
- }
- XSelectInput(sdd(), side->help, KeyPressMask|ExposureMask);
-
- XSelectInput(sdd(), side->msg, ExposureMask);
- XSelectInput(sdd(), side->info, ExposureMask);
- XSelectInput(sdd(), side->prompt, ExposureMask);
- XSelectInput(sdd(), side->timemode, ExposureMask);
- XSelectInput(sdd(), side->clock, ExposureMask);
- XSelectInput(sdd(), side->sides, ExposureMask);
- XSelectInput(sdd(), side->world, ExposureMask);
- }
-
- /* Move windows and change their sizes to correspond with the new sizes of */
- /* viewports, etc */
-
- reset_misc(side)
- Side *side;
- {
- Pixmap dots;
- XSizeHints hints;
- XGCValues values;
- unsigned int gcmask;
-
- dots = (side->bonw ? sd()->bwdots : sd()->wbdots);
-
- XResizeWindow(sdd(), side->main, side->mw, side->mh);
- hints.width = side->mw; hints.height = side->mh;
- hints.min_width = side->mw; hints.min_height = side->mh;
- hints.flags = PSize|PMinSize;
- XSetNormalHints(sdd(), side->main, &hints);
-
- XSetWindowBackgroundPixmap(sdd(), side->main, dots);
- XSetWindowBackground(sdd(), side->msg, side->bgcolor);
- XSetWindowBackground(sdd(), side->info, side->bgcolor);
- XSetWindowBackground(sdd(), side->prompt, side->bgcolor);
- XSetWindowBackground(sdd(), side->map, side->bgcolor);
- XSetWindowBackground(sdd(), side->timemode, side->bgcolor);
- XSetWindowBackground(sdd(), side->clock, side->bgcolor);
- XSetWindowBackground(sdd(), side->state, side->bgcolor);
- XSetWindowBackground(sdd(), side->help, side->bgcolor);
- XSetWindowBackground(sdd(), side->sides, side->bgcolor);
- XSetWindowBackground(sdd(), side->world, side->bgcolor);
- XSetWindowBorder(sdd(), side->msg, side->fgcolor);
- XSetWindowBorder(sdd(), side->info, side->fgcolor);
- XSetWindowBorder(sdd(), side->prompt, side->fgcolor);
- XSetWindowBorder(sdd(), side->map, side->fgcolor);
- XSetWindowBorder(sdd(), side->timemode, side->fgcolor);
- XSetWindowBorder(sdd(), side->clock, side->fgcolor);
- XSetWindowBorder(sdd(), side->state, side->fgcolor);
- XSetWindowBorder(sdd(), side->help, side->fgcolor);
- XSetWindowBorder(sdd(), side->sides, side->fgcolor);
- XSetWindowBorder(sdd(), side->world, side->fgcolor);
-
- gcmask = GCForeground | GCBackground;
- values.foreground = side->fgcolor;
- values.background = side->bgcolor;
- XChangeGC(sdd(), sd()->gc, gcmask, &values);
- XChangeGC(sdd(), sd()->flashgc, gcmask, &values);
- XChangeGC(sdd(), sd()->textgc, gcmask, &values);
- XChangeGC(sdd(), sd()->icongc, gcmask, &values);
- XChangeGC(sdd(), sd()->unitgc, gcmask, &values);
- values.foreground = side->bgcolor;
- values.background = side->fgcolor;
- XChangeGC(sdd(), sd()->invicongc, gcmask, &values);
- }
-
- /* Alter the size and position of a window. */
-
- change_window(side, win, x, y, w, h)
- Side *side;
- Window win;
- int x, y, w, h;
- {
- unsigned int mask;
- XWindowChanges changes;
-
- if (active_display(side)) {
- if (x >= 0) {
- if (w >= 0) {
- mask = CWX | CWY | CWWidth | CWHeight;
- changes.x = x; changes.y = y;
- changes.width = w; changes.height = h;
- } else {
- mask = CWX | CWY;
- changes.x = x; changes.y = y;
- }
- } else {
- mask = CWWidth | CWHeight;
- changes.width = w; changes.height = h;
- }
- }
- XConfigureWindow(sdd(), win, mask, &changes);
- }
-
- /* Return the number of colors - this is used to guess about monochromeness. */
-
- display_colors(side)
- Side *side;
- {
- return XDisplayCells(sdd(), DefaultScreen(sdd()));
- }
-
- white_color(side)
- Side *side;
- {
- /* return request_color(side,"white");*/
- return WhitePixel(sdd(), DefaultScreen(sdd()));
- }
-
- black_color(side)
- Side *side;
- {
- /* return request_color(side,"black");*/
- return BlackPixel(sdd(), DefaultScreen(sdd()));
- }
-
- /* Get a color set up and warn if not getting what was asked for. */
-
- long
- request_color(side, name)
- Side *side;
- char *name;
- {
- XColor c, avail;
-
- if (Debug) printf("Allocating %s\n", name);
- XAllocNamedColor(sdd(), side->cmap, name, &avail, &c);
- if ( abs(c.red - avail.red) >= COLOR_DIFF ||
- abs(c.green - avail.green) >= COLOR_DIFF ||
- abs(c.blue - avail.blue) >= COLOR_DIFF ) {
- fprintf(stderr, "Warning: %s color (%d) not exact on \"%s\"!\n",
- name, c.pixel, side->host);
- fprintf(stderr, "Is %d %d %d instead of %d %d %d\n",
- avail.red, avail.green, avail.blue, c.red, c.green, c.blue);
- }
- return avail.pixel;
- }
-
- /* Main funnel for input returns both mouse and keyboard events, and maybe */
- /* other kinds eventually. Some events like window exposure are handled */
- /* strictly locally. */
-
- get_input()
- {
- #ifdef SELECT2
- int i, mask;
- Side *side, *asides[32];
-
- mask = 0;
- for_all_sides(side) {
- if (active_display(side)) {
- mask |= (1 << ConnectionNumber(sdd()));
- asides[ConnectionNumber(sdd())] = side;
- while (XPending(sdd()) > 0) {
- process_events(side);
- }
- side->lasttime = time(0);
- }
- }
- if (Debug) {
- printf("Waiting for input from ");
- for_all_sides(side)
- if (active_display(side)) printf("%s ", side->host);
- printf("\n");
- }
- if (select(32, &mask, 0, 0, 0) < 0) {
- fprintf(stderr, "error in select!\n");
- abort();
- } else {
- for (i = 0; i < 32; ++i) {
- if (mask & (1 << i)) {
- process_events(asides[i]);
- asides[i]->timeleft -= (time(0) - asides[i]->lasttime);
- update_clock(asides[i]);
- }
- }
- }
- #else
- extern Side *curside;
-
- /* No simultaneity, but there's no portable way to do it, sigh */
- if (active_display(curside) && humanside(curside)) {
- if (Debug) printf("Waiting for input from %s\n", curside->host);
- process_events(curside);
- }
- #endif /* SELECT2 */
- }
-
- /* Look at a single event and fill the request structure appropriately. */
-
- process_events(side)
- Side *side;
- {
- XEvent evt;
- char buf[BUFSIZE];
- int nchar, rawx, rawy;
- int win;
- unsigned int junk;
-
- side->reqtype = GARBAGE;
- XNextEvent(sdd(), &evt);
- switch (evt.type) {
- case KeyPress:
- nchar = XLookupString(&evt, buf, BUFSIZE, NULL, NULL);
- if (nchar > 0) {
- side->reqtype = KEYBOARD;
- side->reqch = *buf;
- if (Debug) printf("Host %s returns key '%c'\n",
- side->host, side->reqch);
- }
- break;
- case ButtonPress:
- win = evt.xbutton.window;
- if (win == side->map) {
- rawx = evt.xbutton.x; rawy = evt.xbutton.y;
- side->reqtype = MAPPOS;
- deform(side, rawx, rawy, &(side->reqx), &(side->reqy));
- if (Debug) printf("Host %s returns map %d %d\n",
- side->host, side->reqx, side->reqy);
- } else if (win == side->state) {
- rawx = evt.xbutton.x; rawy = evt.xbutton.y;
- side->reqtype = UNITTYPE;
- side->requtype = rawy / max(side->hh, side->fh);
- if (Debug) printf("Host %s returns unit type %d\n",
- side->host, side->requtype);
- }
- break;
- case Expose:
- win = evt.xexpose.window;
-
- /* if this is the first expose, install our colormap
- * (if we need to)
- */
- if (side->InstallCmap) {
- side->InstallCmap = 0;
- XInstallColormap(sdd(), side->cmap);
- }
-
- /* get rid of all other Expose events on queue */
- while (XCheckTypedWindowEvent(sdd(), win, Expose, &evt));
-
- /* don't need to check which window got event,
- * because we take care of that with the
- * event masks.
- */
-
- clear_window(side, win);
- if (win == side->map)
- show_map(side);
- else if (win == side->state)
- show_state(side);
- else if (win == side->world)
- show_world(side);
- else if (win == side->msg)
- show_note(side);
- else if (win == side->info)
- show_info(side);
- else if (win == side->prompt)
- show_prompt(side);
- else if (win == side->sides)
- show_all_sides(side);
- else if (win == side->timemode)
- show_timemode(side);
- else if (win == side->clock)
- show_clock(side);
- else if (win == side->help) {
- side->reqch = '\014';
- x_help(side); /* redraw help window */
- }
- flush_output(side);
-
- if (Debug) printf("Host %s exposes itself\n", side->host);
- return FALSE;
- break;
- case ConfigureNotify:
- win = evt.xexpose.window;
-
- /* window has been resized */
- if (win == side->map) {
- undraw_box(side);
-
- side->vw = evt.xconfigure.width / side->hw;
- side->vh = evt.xconfigure.height / side->hch;
- side->vw2 = side->vw / 2;
- side->vh2 = side->vh / 2;
- /* flush_input(side);*/
- set_sizes(side); /* adjust viewport */
- /* count on exposure event to draw map */
- draw_box(side);
- }
- else if (win == side->main) {
- int sy, sdy;
- int remain;
-
- remain = side->fh * (INFOLINES + 1) + 3 * side->bd;
- side->nh = (evt.xconfigure.height - remain) / side->fh;
- side->nh = min(side->nh, MAXNOTES);
- side->nh = max(1, side->nh);
- set_sizes(side);
-
- sy = 0; sdy = side->nh * side->fh;
- change_window(side, side->msg, 0, sy, side->lw, sdy);
- sy += sdy + side->bd; sdy = INFOLINES * side->fh;
- change_window(side, side->info, 0, sy, side->lw, sdy);
- sy += sdy + side->bd; sdy = 1 * side->fh;
- change_window(side, side->prompt, 0, sy, side->lw, sdy);
- change_window(side, side->timemode,
- side->lw + side->fw, side->th - 4 * side->fh, -1, -1);
- change_window(side, side->sides, side->lw+1, 0, -1, -1);
- /* count on expose to draw all windows */
- }
- break;
-
- case DestroyNotify:
- case CirculateNotify:
- case GravityNotify:
- case MapNotify:
- case ReparentNotify:
- case UnmapNotify:
- break;
- default:
- #if 0
- case_panic("event type", evt.type);
- #endif
- break;
- }
- }
-
- /* Freese everything until given side supplies input, use sparingly. */
-
- freeze_wait(side)
- Side *side;
- {
- XEvent evt;
- char buf[BUFSIZE];
- int nchar;
-
- if (Debug) printf("Waiting for a %s event\n", side->host);
- flush_input(side);
- while(TRUE) {
- XNextEvent(sdd(), &evt);
- if (evt.type == KeyPress) {
- nchar = XLookupString(&evt, buf, BUFSIZE, NULL, NULL);
- if (nchar > 0)
- return *buf;
- else
- return '\0';
- }
- }
- }
-
- /* Get rid of extra key/mouse clicks. */
-
- flush_input(side)
- Side *side;
- {
- XEvent evt;
-
- /* if (humanside(side)) XSync(sdd(), TRUE);*/
- if (humanside(side)) {
- while (XCheckTypedWindowEvent(sdd(), side->main, KeyPress, &evt));
- while (XCheckTypedWindowEvent(sdd(), side->help, KeyPress, &evt));
- while (XCheckTypedWindowEvent(sdd(), side->map, ButtonPress, &evt));
- while (XCheckTypedWindowEvent(sdd(), side->state, ButtonPress, &evt));
- XSync(sdd(), FALSE);
- }
- }
-
- /* Trivial abstraction - sometimes other routines like to ensure all output */
- /* actually on the screen. */
-
- flush_output(side)
- Side *side;
- {
- if (humanside(side)) XFlush(sdd());
- }
-
- /* General window clearing. */
-
- clear_window(side, win)
- Side *side;
- Window win;
- {
- XClearWindow(sdd(), win);
- }
-
- /* Draw a single horizontal constant-color bar on the world map. If part */
- /* would not be drawn because of the map's obliqueness, cut it in two and */
- /* wrap one of the pieces around. */
-
- draw_bar(side, x, y, len, color)
- Side *side;
- int x, y, len, color;
- {
- int sx1, sx2, sy, sww;
-
- w_xform(side, x, y, &sx1, &sy);
- w_xform(side, x + len, y, &sx2, &sy);
- sww = side->mm * world.width;
- XSetFillStyle(sdd(), sd()->gc, FillSolid);
- XSetForeground(sdd(), sd()->gc, color);
- if (sx1 < sww && sx2 >= sww) {
- XFillRectangle(sdd(), side->world, sd()->gc,
- sx1, sy, (unint) sww - sx1, (unint) side->mm);
- XFillRectangle(sdd(), side->world, sd()->gc,
- 0, sy, (unint) sx2 - sww, (unint) side->mm);
- } else {
- sx1 %= sww;
- sx2 %= sww;
- XFillRectangle(sdd(), side->world, sd()->gc,
- sx1, sy, (unint) sx2 - sx1, (unint) side->mm);
- }
- #ifdef STUPIDFLUSH
- XFlush(sdd());
- #endif /* STUPIDFLUSH */
- }
-
- /* Invert the outline box on the world map. This is a little tricky, */
- /* because we want the lines to run through the middle of the world's */
- /* hexes, and because the line drawn should not overlap (or the overlaps */
- /* will be doubly inverted and look strange). */
-
- invert_box(side, vcx, vcy)
- Side *side;
- int vcx, vcy;
- {
- int x1, y1, x2, y2, sx1, sy1, sx2, sy2, mm2 = side->mm/2;
-
- x1 = vcx - side->vw2 + side->vh2/2; y1 = vcy - side->vh2;
- x2 = vcx + side->vw2 - side->vh2/2; y2 = vcy + side->vh2;
- w_xform(side, x1, y1, &sx1, &sy1);
- w_xform(side, x2, y2, &sx2, &sy2);
- sx1 += mm2; sy1 -= mm2; sx2 += mm2; sy2 += mm2;
- XSetFunction(sdd(), sd()->gc, GXinvert);
- /* is this next call really necessary? */
- XSetLineAttributes(sdd(), sd()->gc, 1, LineSolid, CapButt, JoinMiter);
- XDrawLine(sdd(), side->world, sd()->gc, sx1, sy1, sx2, sy1);
- XDrawLine(sdd(), side->world, sd()->gc, sx2, sy1-1, sx2, sy2+1);
- XDrawLine(sdd(), side->world, sd()->gc, sx2, sy2, sx1, sy2);
- XDrawLine(sdd(), side->world, sd()->gc, sx1, sy2+1, sx1, sy1-1);
- XSetFunction(sdd(), sd()->gc, GXcopy);
- }
-
- /* This interfaces higher-level drawing decisions to the rendition of */
- /* individual pieces of display. */
-
- draw_terrain_row(side, sx, sy, buf, len, color)
- Side *side;
- int sx, sy, len, color;
- char *buf;
- {
- sy += sd()->iconfont->max_bounds.ascent;
- XSetForeground(sdd(), sd()->icongc, color);
- XDrawString(sdd(), side->map, sd()->icongc, sx, sy, buf, len);
- #ifdef STUPIDFLUSH
- XFlush(sdd());
- #endif /* STUPIDFLUSH */
- }
-
- /* Flash a pair of lines up, slow enough to draw the eye, but not so slow */
- /* as to get in the way. */
-
- flash_position(side, sx, sy, tm)
- Side *side;
- int sx, sy, tm;
- {
- int sx1, sy1, sx2, sy2;
-
- if (tm > 0) {
- sx1 = sx - 50 + side->hw/2; sy1 = sy + 50 + side->hch/2;
- sx2 = sx + 50 + side->hw/2; sy2 = sy - 50 + side->hch/2;
- XDrawLine(sdd(), side->map, sd()->flashgc, sx1, sy1, sx2, sy2);
- XDrawLine(sdd(), side->map, sd()->flashgc, sx1, sy2, sx2, sy1);
- flush_output(side);
- nap(tm);
- XDrawLine(sdd(), side->map, sd()->flashgc, sx1, sy1, sx2, sy2);
- XDrawLine(sdd(), side->map, sd()->flashgc, sx1, sy2, sx2, sy1);
- }
- }
-
- /* The "cursor icon" is just a pair of special chars - nothing to do with */
- /* X's notion of cursors. */
-
- draw_cursor_icon(side, sx, sy)
- Side *side;
- int sx, sy;
- {
- sy += sd()->iconfont->max_bounds.ascent;
- XDrawString(sdd(), side->map, sd()->invicongc, sx, sy, "[", 1);
- XSetForeground(sdd(), sd()->icongc, side->fgcolor);
- XDrawString(sdd(), side->map, sd()->icongc, sx, sy, "]", 1);
- }
-
- /* Draw the icon for a hex (given as a char). */
-
- draw_hex_icon(side, win, sx, sy, color, ch)
- Side *side;
- Window win;
- int sx, sy, color;
- char ch;
- {
- XSetForeground(sdd(), sd()->varicongc, color);
- sy += sd()->iconfont->max_bounds.ascent;
- XDrawString(sdd(), win, sd()->varicongc, sx, sy, &ch, 1);
- }
-
- /* Draw the number of an unfriendly side (never called for own units). */
-
- draw_side_number(side, win, sx, sy, n, color)
- Side *side;
- Window win;
- int sx, sy, n, color;
- {
- char ch = n + '0';
-
- if (n >= 0) {
- XSetForeground(sdd(), sd()->varicongc, color);
- sy += sd()->iconfont->max_bounds.ascent;
- XDrawString(sdd(), win, sd()->varicongc, sx, sy, &ch, 1);
- }
- }
-
- draw_blast_icon(side, win, sx, sy, type, color)
- Side *side;
- Window win;
- int sx, sy, color;
- char type;
- {
- char buf[1];
-
- XSetForeground(sdd(), sd()->varicongc, color);
- buf[0] = type;
- sy += sd()->iconfont->max_bounds.ascent;
- XDrawString(sdd(), win, sd()->varicongc, sx, sy, buf, 1);
- }
-
- /* Flash the player's screen in an unmistakable way. */
-
- invert_whole_map(side)
- Side *side;
- {
- int sw = side->vw * side->hw, sh = side->vh * side->hh;
-
- /* GC needs to be set for inverted drawing */
- XSetFunction(sdd(), sd()->gc, GXinvert);
- XFillRectangle(sdd(), side->map, sd()->gc, 0, 0, sw, sh);
- XSetFunction(sdd(), sd()->gc, GXcopy);
- flush_output(side);
- }
-
- /* Draw just one of the mushroom cloud shapes. */
-
- draw_mushroom(side, x, y, i)
- Side *side;
- int x, y, i;
- {
- int sx, sy;
- int color;
-
- color = ((side->monochrome || i == 3) ? side->fgcolor : side->bgcolor);
- xform(side, unwrap(side, x), y, &sx, &sy);
- XSetForeground(sdd(), sd()->unitgc, color);
- XSetClipMask(sdd(), sd()->unitgc, sd()->bombpics[i]);
- XSetClipOrigin(sdd(), sd()->unitgc, sx-BH/4, sy-BH/2);
- XFillRectangle(sdd(), side->map, sd()->unitgc, sx-BH/4, sy-BH/2, BH, BH);
- flush_output(side);
- }
-
- /* Confirm that we can indeed do bar graph displays. */
-
- bar_graphs(side) Side *side; { return TRUE; }
-
- /* Do yet another X-toolkit-type function. This draws a bar graph. */
-
- draw_graph(side, number, amount, total, critical, title)
- Side *side;
- int number, amount, total, critical;
- {
- int boxwidth, boxheight, boxoffset, boxleft, barwidth, barheight;
-
- if (total > 0) {
- boxwidth = 5*side->fw;
- boxheight = (INFOLINES-1)*side->fh - 2*side->margin;
- boxoffset = side->margin;
- boxleft = 30*side->fw + number * boxwidth;
- barwidth = boxwidth / 3;
- barheight = (boxheight * amount) / total;
- XSetForeground(sdd(), sd()->gc, side->fgcolor);
- XFillRectangle(sdd(), side->info, sd()->gc,
- boxleft + boxwidth/3 - 1, boxoffset - 1,
- barwidth + 2, boxheight + 2);
- XSetForeground(sdd(), sd()->gc, side->bgcolor);
- XFillRectangle(sdd(), side->info, sd()->gc,
- boxleft + boxwidth/3, boxoffset,
- barwidth, boxheight);
- if ( amount > critical)
- XSetForeground(sdd(), sd()->gc, side->goodcolor);
- else
- XSetForeground(sdd(), sd()->gc, side->badcolor);
- XFillRectangle(sdd(), side->info, sd()->gc,
- boxleft + boxwidth/3, boxoffset + boxheight - barheight,
- barwidth, barheight);
- draw_text(side, side->info,
- boxleft+(boxwidth-strlen(title)*side->fw)/2,
- (INFOLINES-1)*side->fh, title, side->fgcolor);
- }
- }
-
- /* Splash a unit image (either bitmap or font char) onto some window. */
-
- draw_unit_icon(side, win, x, y, u, color)
- Side *side;
- Window win;
- int x, y, u, color;
- {
- char buf[1];
-
- y += 3; /* fudge factor to make x11 look */
- x += 2; /* like X10 (ugh). */
- if (utypes[u].bitmapname != NULL ) {
- XSetForeground(sdd(), sd()->unitgc, color);
- XSetClipMask(sdd(), sd()->unitgc, sd()->unitpics[u]);
- XSetClipOrigin(sdd(), sd()->unitgc, x, y);
- XFillRectangle(sdd(), win, sd()->unitgc, x, y, side->uw, side->uh);
- } else {
- XSetForeground(sdd(), sd()->unittextgc, color);
- buf[0] = utypes[u].uchar;
- y += sd()->unitfont->max_bounds.ascent;
- XDrawString(sdd(), win, sd()->unittextgc, x, y, buf, 1);
- }
- }
-
- /* General text drawer. */
-
- draw_text(side, win, x, y, str, color)
- Side *side;
- Window win;
- int x, y, color;
- char *str;
- {
- y += sd()->textfont->max_bounds.ascent;
- if (color != side->bgcolor) {
- XSetForeground(sdd(), sd()->textgc, color);
- XDrawImageString(sdd(), win, sd()->textgc, x, y, str, strlen(str));
- } else {
- XSetForeground(sdd(), sd()->textgc, side->bgcolor);
- XSetBackground(sdd(), sd()->textgc, side->fgcolor);
- XDrawImageString(sdd(), win, sd()->textgc, x, y, str, strlen(str));
- XSetBackground(sdd(), sd()->textgc, side->bgcolor);
- }
- #ifdef STUPIDFLUSH
- XFlush(sdd());
- #endif /* STUPIDFLUSH */
- }
-
- /* Draw a line through some side's title. */
-
- draw_scratchout(side, pos)
- Side *side;
- int pos;
- {
- XSetForeground(sdd(), sd()->textgc, side->fgcolor);
- XDrawLine(sdd(), side->sides, sd()->textgc, 0, pos, 30*side->fw, pos);
- }
-
- /* Beep the beeper! */
-
- beep(side)
- Side *side;
- {
- XBell(sdd(), DefaultScreen(sdd()));
- }
-
- /* Little routines to pop up the help window and make it go away again */
- /* They only get called when display is in use. */
-
- reveal_help(side)
- Side *side;
- {
- XEvent evt;
-
- XMapWindow(sdd(), side->help);
- /* wait until this window is exposed to return. */
- XWindowEvent(sdd(), side->help, ExposureMask, &evt);
- return TRUE;
- }
-
- conceal_help(side)
- Side *side;
- {
- XUnmapWindow(sdd(), side->help);
- flush_output(side);
- }
-
- /* Shut a single display down, but only if there's one to operate on. */
- /* Hit the display slot, for safety. */
-
- close_display(side)
- Side *side;
- {
- XCloseDisplay(sdd());
- side->display = (long) NULL;
- }
-
- /* read options from server resource manager */
-
- read_options(side)
- Side *side;
- {
- char *option;
-
- option = XGetDefault(sdd(), PROGRAMNAME, "Split");
- side->split = parse_boolean(option);
- option = XGetDefault(sdd(), PROGRAMNAME, "Graph");
- side->graphical = parse_boolean(option);
- option = XGetDefault(sdd(), PROGRAMNAME, "DisplayMode");
- if (option)
- side->showmode = atoi(option) % 4;
- option = XGetDefault(sdd(), PROGRAMNAME, "Inverse");
- side->bonw = parse_boolean(option);
- option = XGetDefault(sdd(), PROGRAMNAME, "Monochrome");
- side->monochrome = parse_boolean(option);
- option = XGetDefault(sdd(), PROGRAMNAME, "InstallCmap");
- side->InstallCmap = parse_boolean(option);
- option = XGetDefault(sdd(), PROGRAMNAME, "NoticeLines");
- if (option)
- side->nh = atoi(option);
- option = XGetDefault(sdd(), PROGRAMNAME, "MapWidth");
- if (option) {
- side->vw = atoi(option);
- side->vw = min( max(side->vw, MINWIDTH), world.width);
- }
- option = XGetDefault(sdd(), PROGRAMNAME, "MapHeight");
- if (option) {
- side->vh = atoi(option);
- side->vh = min( max(side->vh, MINHEIGHT), world.height);
- }
- }
-
- /* parse a boolean string */
- int
- parse_boolean(string)
- char *string;
- {
- if (string == 0)
- return 0;
- if (strcmp(string, "yes") == 0 ||
- strcmp(string, "on") == 0 ||
- strcmp(string, "true") == 0)
- return 1;
- else
- return 0;
- }
-
- init_cmaps(side)
- Side *side;
- {
- int i;
- unsigned long black, white;
- unsigned long *pixels;
- XColor color_def, rgb_def;
- Visual *visual;
-
- side->cmap = DefaultColormap(sdd(), DefaultScreen(sdd()));
- if (check_colors(side)) {
- if (Debug) printf("xconq: using default colormap\n");
- return TRUE; /* use default colormap */
- }
-
- if (Debug) printf("xconq: making new colormap\n");
- visual = DefaultVisual(sdd(),DefaultScreen(sdd()));
- side->cmap = XCreateColormap(sdd(), DefaultRootWindow(sdd()),
- visual, AllocNone);
-
- pixels = (unsigned long *)
- malloc( sizeof(unsigned long) * visual->map_entries);
- XAllocColorCells( sdd(), side->cmap, FALSE, 0, 0,
- pixels, visual->map_entries);
- white = WhitePixel(sdd(), DefaultScreen(sdd()));
- black = BlackPixel(sdd(), DefaultScreen(sdd()));
- XStoreNamedColor(sdd(), side->cmap, "white", white,
- DoRed | DoGreen | DoBlue);
- XStoreNamedColor(sdd(), side->cmap, "black", black,
- DoRed | DoGreen | DoBlue);
-
- for( i=0; i < visual->map_entries; i++) {
- if (i == black || i == white)
- continue;
- *pixels = i;
- XFreeColors(sdd(), side->cmap, pixels, 1, 0);
- }
- free(pixels);
-
- return TRUE;
-
- }
-
-
- check_colors(side)
- Side *side;
- {
- int i;
- long colors[MAX_COLORS];
- long planes;
-
- for(i=MAX_COLORS; i>=MIN_COLORS; i--) {
- if (XAllocColorCells(sdd(), side->cmap, FALSE, &planes, 0,
- colors, i))
- break;
- }
- if (i >= MIN_COLORS) {
- XFreeColors(sdd(), side->cmap, colors, i, 0);
- return i;
- }
- else {
- return 0;
- }
- }
-
- /* Completely redo a screen, making no assumptions about appearance. */
- /* This one is used frequently, especially when a window is exposed. */
-
- redraw(side)
- Side *side;
- {
- XEvent report;
-
- if (active_display(side)) {
- report.xexpose.type = Expose;
- report.xexpose.display = sdd();
- report.xexpose.window = side->main;
- report.xexpose.x = report.xexpose.y =
- report.xexpose.width = report.xexpose.height = 1;
- expose(side,&report,side->main);
- expose(side,&report,side->map);
- expose(side,&report,side->world);
- expose(side,&report,side->state);
- expose(side,&report,side->msg);
- expose(side,&report,side->info);
- expose(side,&report,side->prompt);
- expose(side,&report,side->sides);
- expose(side,&report,side->timemode);
- expose(side,&report,side->clock);
- expose(side,&report,side->help);
- flush_output(side);
- flush_input(side);
- }
- }
-
- static
- expose(side,event,window)
- Side *side;
- XEvent *event;
- Window window;
- {
- int cc;
- event->xexpose.window = window;
- cc = XSendEvent(sdd(),window,False,ExposureMask,event);
- }
-
- add_font_path(side,newelement)
- Side *side;
- char *newelement;
- {
- char **fontpath, **newpath;
- int i,npaths;
-
- fontpath = XGetFontPath(sdd(), &npaths);
- newpath = (char **) malloc((npaths+1) * (sizeof(char *)));
- for(i=0;i<npaths;i++) {
- newpath[i] = fontpath[i];
- }
- newpath[i] = newelement;
- XSetFontPath(sdd(),newpath,npaths+1);
- free(newpath);
- if (fontpath)
- XFreeFontPath(fontpath);
- }
-